//
//  vdEvent.m
//  Void Dead
//
//  Created by Sidney Just on 27.11.09.
//
//  Copyright © 2009 by Sidney Just
//  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
//  documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
//  the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 
//  and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
//  INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
//  PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 
//  FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
//  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

#import "vdEventHandler.h"
#import "vdEventReceiver.h"

// \cond
@interface vdEventReceiver (_private)
- (void)onEvent:(vdEventMessage *)message;
@end
// \endcond

@implementation vdEventHandler


#pragma mark -
#pragma mark Events

- (void)fireEvent:(vdEventMessage *)aMessage {
	if(aMessage->type == vdNone)
		return;
	
	// -Event-
	for(int i=0; i<receiverCount; i++)
	{
		if(aMessage->type & receiver[i].listenTo)
		{
			[receiver[i] onEvent:aMessage];
		}
	}
}

- (void)fireEvent:(vdEventType)aType sender:(id)sender data:(void *)aData {
	vdEventMessage *message = (vdEventMessage *)malloc(sizeof(vdEventMessage));
	message->sender = sender;
	message->type = aType;
	message->data = aData;
	
	[self fireEvent:message];
	
	free(message);
}

#pragma mark -
#pragma mark Receiver

- (void)addReceiver:(vdEventReceiver *)aReceiver {
	receiverCount += 1;
	receiver = (vdEventReceiver **)realloc(receiver, receiverCount*sizeof(vdEventReceiver));
	receiver[receiverCount-1] = aReceiver;
}

- (void)removeReceiver:(vdEventReceiver *)aReceiver {
	for(int i=0; i<receiverCount; i++)
	{
		if(receiver[i] == aReceiver)
		{
			for(int j=i; j<receiverCount-1; j++)
			{
				receiver[j] = receiver[j+1];
			}
			
			receiverCount -= 1;
			receiver = (vdEventReceiver **)realloc(receiver, receiverCount*sizeof(vdEventReceiver));
			return;
		}
	}
}

#pragma mark -
#pragma mark Con/Destructor

static vdEventHandler *_sharedHandler = NULL;

+ (vdEventHandler *)sharedEventHandler {
	if(!_sharedHandler)
	{
		vdEventHandler *temp = [[vdEventHandler alloc] init];
		_sharedHandler = temp;
	}
	return _sharedHandler;
}

- (id)init {
	if(_sharedHandler)
	{
		[self release];
		return _sharedHandler;
	}
	
	if(self = [super init])
	{
		receiverCount = 0;
		receiver = (vdEventReceiver **)malloc(sizeof(vdEventReceiver));
	}
	return self;
}

- (void)dealloc {
	for(int i=0; i<receiverCount; i++)
	{
		[receiver[i] release];
	}
	
	free(receiver);
	
	[super dealloc];
}

@end
